"""
五子棋禁手规则
仅对黑棋（先手）有效
包括：三三禁手、四四禁手、长连禁手
"""


class ForbiddenRules:
    """禁手规则检测类"""
    
    @staticmethod
    def check_forbidden(board, board_size, row, col, player):
        """
        检查是否触发禁手（仅对黑棋有效）
        :param board: 棋盘状态
        :param board_size: 棋盘大小
        :param row: 落子的行坐标
        :param col: 落子的列坐标
        :param player: 当前玩家（1为黑棋，2为白棋）
        :return: 禁手类型字符串，或None
        """
        # 禁手规则仅对黑棋（玩家1）有效
        if player != 1:
            return None
        
        # 检查长连禁手（六连或更多）
        if ForbiddenRules.check_overline(board, board_size, row, col, player):
            return "长连禁手"
        
        # 检查四四禁手
        if ForbiddenRules.check_double_four(board, board_size, row, col, player):
            return "四四禁手"
        
        # 检查三三禁手
        if ForbiddenRules.check_double_three(board, board_size, row, col, player):
            return "三三禁手"
        
        return None
    
    @staticmethod
    def check_overline(board, board_size, row, col, player):
        """
        检查长连禁手（六连或更多）
        :param board: 棋盘状态
        :param board_size: 棋盘大小
        :param row: 行坐标
        :param col: 列坐标
        :param player: 玩家
        :return: 是否长连
        """
        directions = [(0, 1), (1, 0), (1, 1), (1, -1)]
        
        for dx, dy in directions:
            count = 1
            # 正向
            x, y = row + dx, col + dy
            while 0 <= x < board_size and 0 <= y < board_size and board[x][y] == player:
                count += 1
                x += dx
                y += dy
            # 反向
            x, y = row - dx, col - dy
            while 0 <= x < board_size and 0 <= y < board_size and board[x][y] == player:
                count += 1
                x -= dx
                y -= dy
            
            if count >= 6:
                return True
        
        return False
    
    @staticmethod
    def check_double_four(board, board_size, row, col, player):
        """
        检查四四禁手（同时形成两个或以上的四）
        :param board: 棋盘状态
        :param board_size: 棋盘大小
        :param row: 行坐标
        :param col: 列坐标
        :param player: 玩家
        :return: 是否四四
        """
        four_count = 0
        directions = [(0, 1), (1, 0), (1, 1), (1, -1)]
        
        for dx, dy in directions:
            if ForbiddenRules.is_four(board, board_size, row, col, player, dx, dy):
                four_count += 1
        
        return four_count >= 2
    
    @staticmethod
    def check_double_three(board, board_size, row, col, player):
        """
        检查三三禁手（同时形成两个或以上的活三）
        :param board: 棋盘状态
        :param board_size: 棋盘大小
        :param row: 行坐标
        :param col: 列坐标
        :param player: 玩家
        :return: 是否三三
        """
        live_three_count = 0
        directions = [(0, 1), (1, 0), (1, 1), (1, -1)]
        
        for dx, dy in directions:
            if ForbiddenRules.is_live_three(board, board_size, row, col, player, dx, dy):
                live_three_count += 1
        
        return live_three_count >= 2
    
    @staticmethod
    def is_four(board, board_size, row, col, player, dx, dy):
        """
        判断某个方向是否形成四（包括冲四和活四）
        :param board: 棋盘状态
        :param board_size: 棋盘大小
        :param row: 行坐标
        :param col: 列坐标
        :param player: 玩家
        :param dx: x方向
        :param dy: y方向
        :return: 是否为四
        """
        count = 1
        empty_count = 0
        
        # 正向检查
        x, y = row + dx, col + dy
        while 0 <= x < board_size and 0 <= y < board_size:
            if board[x][y] == player:
                count += 1
                x += dx
                y += dy
            elif board[x][y] == 0 and empty_count == 0:
                empty_count += 1
                x += dx
                y += dy
            else:
                break
        
        # 反向检查
        x, y = row - dx, col - dy
        while 0 <= x < board_size and 0 <= y < board_size:
            if board[x][y] == player:
                count += 1
                x -= dx
                y -= dy
            elif board[x][y] == 0 and empty_count == 0:
                empty_count += 1
                x -= dx
                y -= dy
            else:
                break
        
        # 四个棋子（可能中间有一个空位）
        return count == 4
    
    @staticmethod
    def is_live_three(board, board_size, row, col, player, dx, dy):
        """
        判断某个方向是否形成活三（两端都是空位的三子）
        :param board: 棋盘状态
        :param board_size: 棋盘大小
        :param row: 行坐标
        :param col: 列坐标
        :param player: 玩家
        :param dx: x方向
        :param dy: y方向
        :return: 是否为活三
        """
        count = 1
        left_empty = False
        right_empty = False
        
        # 正向检查
        x, y = row + dx, col + dy
        while 0 <= x < board_size and 0 <= y < board_size:
            if board[x][y] == player:
                count += 1
                x += dx
                y += dy
            elif board[x][y] == 0:
                right_empty = True
                break
            else:
                break
        
        # 反向检查
        x, y = row - dx, col - dy
        while 0 <= x < board_size and 0 <= y < board_size:
            if board[x][y] == player:
                count += 1
                x -= dx
                y -= dy
            elif board[x][y] == 0:
                left_empty = True
                break
            else:
                break
        
        # 活三：三个棋子且两端都是空位
        return count == 3 and left_empty and right_empty
